#include "Avalon/IO/SizeDeclarativeWriter.hpp"
#include <boost/cstdint.hpp>
#include "Avalon/IO/Buffer.hpp"

using namespace Avalon;
using namespace Avalon::IO;
using namespace Avalon::Threading;
using namespace boost;

SizeDeclarativeWriter::SizeDeclarativeWriter(Carry<Writer> destination)
    : m_destination(destination) {}

SizeDeclarativeWriter::~SizeDeclarativeWriter() {}

void SizeDeclarativeWriter::Write(const void* data, int size,
    Out<Async<void> > result) {
  static const int SIZE_OF_INT = 4;
  boost::uint32_t portableInt = ToLittleEndian(
    static_cast<boost::uint32_t>(size));
  Buffer coalescedData(SIZE_OF_INT + size);
  coalescedData.Write(0, reinterpret_cast<const char*>(&portableInt) +
    (sizeof(portableInt) - SIZE_OF_INT), SIZE_OF_INT);
  coalescedData.Write(SIZE_OF_INT, data, size);
  m_destination->Write(coalescedData, Store(result));
}

void SizeDeclarativeWriter::Write(const Buffer& data,
    Out<Async<void> > result) {
  return Write(data.GetData(), data.GetSize(), Store(result));
}
